package cn.bugstack.deepseek.executor.model.deepseek;

import cn.bugstack.deepseek.executor.parameter.*;
import cn.bugstack.deepseek.executor.result.ResultHandler;
import cn.bugstack.deepseek.executor.Executor;
import cn.bugstack.deepseek.executor.model.deepseek.config.DeepSeekConfig;
import cn.bugstack.deepseek.executor.model.deepseek.domain.DeepSeekCompletionRequest;
import cn.bugstack.deepseek.session.Configuration;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;

import java.util.ArrayList;
import java.util.List;

/**
 * DeepSeek模型执行器，提供每个请求的具体实现
 */
public class DeepSeekModelExecutor implements Executor, cn.bugstack.deepseek.executor.parameter.ParameterHandler<DeepSeekCompletionRequest>, ResultHandler {

    /**
     * 配置信息
     */
    private final DeepSeekConfig deepSeekConfig;
    /**
     * 工厂事件
     */
    private final EventSource.Factory factory;
    /**
     * http 客户端
     */
    private final OkHttpClient okHttpClient;

    public DeepSeekModelExecutor(Configuration configuration){
        this.deepSeekConfig = configuration.getDeepSeekConfig();
        this.factory = configuration.createRequestFactory();
        this.okHttpClient = configuration.getOkHttpClient();
    }


    @Override
    public EventSource completions(cn.bugstack.deepseek.executor.parameter.CompletionRequest completionRequest, EventSourceListener eventSourceListener) throws Exception {
        return completions(null, null, completionRequest, eventSourceListener);
    }

    @Override
    public EventSource completions(String apiHostByUser, String apiKeyByUser, cn.bugstack.deepseek.executor.parameter.CompletionRequest completionRequest, EventSourceListener eventSourceListener) throws Exception {
        // 1. 核心参数校验；不对用户的传参做更改，只返回错误信息。
//        if (!completionRequest.isStream()) {
//            throw new RuntimeException("illegal parameter stream is false!");
//        }

        // 2. 动态设置 Host、Key，便于用户传递自己的信息
        String apiHost = null == apiHostByUser ? deepSeekConfig.getApiHost() : apiHostByUser;
        String apiKey = null == apiKeyByUser ? deepSeekConfig.getApiKey() : apiKeyByUser;

        // 3. 转换参数信息
        DeepSeekCompletionRequest deepSeekCompletionRequest = getParameterObject(completionRequest);

        // 4. 构建请求信息
        Request request = new Request.Builder()
                .header("Authorization", "Bearer " + apiKey)
                .url(apiHost.concat(deepSeekConfig.getV3_chat_completions()))
                .post(RequestBody.create(MediaType.parse(Configuration.APPLICATION_JSON), new ObjectMapper().writeValueAsString(deepSeekCompletionRequest)))
                .build();

        // 5. 返回事件结果
        return factory.newEventSource(request, eventSourceListener);
    }

    /**
     * 同步响应模型，等待大模型API输出完毕之后，再获取结果
     * @param completionRequest
     * @return
     * @throws Exception
     */
    @Override
    public CompletionResponse completions(CompletionRequest completionRequest) throws Exception {
        // sync 同步请求，stream 为 false
        completionRequest.setStream(false);

        DeepSeekCompletionRequest deepSeekCompletionRequest = getParameterObject(completionRequest);

        // 构建请求信息
        Request request = new Request.Builder()
                .header("Authorization", "Bearer " + deepSeekConfig.getApiKey())
                .url(deepSeekConfig.getApiHost().concat(deepSeekConfig.getV3_chat_completions()))
                .post(RequestBody.create(MediaType.parse(Configuration.APPLICATION_JSON), new ObjectMapper().writeValueAsString(deepSeekCompletionRequest)))
                .build();

        Response response = okHttpClient.newCall(request).execute();
        if(!response.isSuccessful()){
            throw new RuntimeException("Request failed");
        }
        return JSON.parseObject(response.body().string(),CompletionResponse.class);
    }

    @Override
    public ImageResponse genImages(ImageRequest imageRequest) throws Exception {
        return null;
    }

    @Override
    public ImageResponse genImages(String apiHostByUser, String apiKeyByUser, ImageRequest imageRequest) throws Exception {
        return null;
    }

    @Override
    public EventSource pictureUnderstanding(PictureRequest pictureRequest, EventSourceListener eventSourceListener) throws Exception {
        return null;
    }

    @Override
    public EventSource pictureUnderstanding(String apiHostByUser, String apiKeyByUser, PictureRequest pictureRequest, EventSourceListener eventSourceListener) throws Exception {
        return null;
    }

    @Override
    public DeepSeekCompletionRequest getParameterObject(CompletionRequest completionRequest) {
        // 转换参数
        List<cn.bugstack.deepseek.executor.model.deepseek.domain.Message> deepSeekMessages = new ArrayList<>();
        List<cn.bugstack.deepseek.executor.parameter.Message> messages = completionRequest.getMessages();
        for (cn.bugstack.deepseek.executor.parameter.Message message : messages) {
            cn.bugstack.deepseek.executor.model.deepseek.domain.Message messageVO = new cn.bugstack.deepseek.executor.model.deepseek.domain.Message();
            messageVO.setContent(message.getContent());
            messageVO.setName(message.getName());
            messageVO.setRole(message.getRole());
            deepSeekMessages.add(messageVO);
        }

        // 封装参数
        DeepSeekCompletionRequest deepSeekCompletionRequest = new DeepSeekCompletionRequest();
        deepSeekCompletionRequest.setModel(completionRequest.getModel());
        deepSeekCompletionRequest.setTemperature(completionRequest.getTemperature());
        deepSeekCompletionRequest.setTopP(completionRequest.getTopP());
        deepSeekCompletionRequest.setStream(completionRequest.isStream());
        deepSeekCompletionRequest.setMessages(deepSeekMessages);
        return deepSeekCompletionRequest;
    }

    @Override
    public EventSourceListener eventSourceListener(EventSourceListener eventSourceListener) {
        return eventSourceListener;
    }
}
